/*
 * PMysqlAPI.h
 *
 *  Created on: Sep 9, 2013
 *      Author: yuliang
 */

#ifndef PMYSQLAPI_H_
#define PMYSQLAPI_H_

#include "PMailBoxs.h"
#include "PLog.h"

#ifdef	__cplusplus
extern "C" {
#endif
#include <mysql/mysql.h>
#include <stddef.h>

#ifndef LOG_MYSQL
#define LOG_MYSQL "logMysql"
#else
#error "LOG_MYSQL define repeat."
#endif

/*
 * @brief       Mysql连接类
 * @auther      lyl
 */
class CDBMysql {
public:
	CDBMysql();
	virtual ~CDBMysql();

	/*
	 * @brief       判断是否连接Mysql
	 * @auther      lyl
	 * @return      bool      : true表示已连接, false表示未连接
	 */
	inline bool IsConnect() const { return m_init; }

	/*
	 * @brief       连接Mysql
	 * @auther      lyl
	 * @param [in]  rdbHost  : ip of mysql
	 * @param [in]  rdbPort  : port of mysql
	 * @param [in]  username : 帐号
	 * @param [in]  password : 密码
	 * @param [in]  db       : db of mysql
	 * @param [in]  poolName : 连接池名字
	 * @param [in]  poolNum  : 连接池大小
	 * @return      bool     : true表示连接成功, false表示连接失败
	 * @note        poolNum必须大于等于MYSQL_POOL_MIN_NUM,小于MYSQL_POOL_MAX_NUM
	 *              poolName默认为NULL,则不使用连接池,非线程完全.
	 */
	bool Connect(const char* rdbHost, int rdbPort, const char* username, const char* password, const char* db);

	/*
	 * @brief       重连某个Mysql连接句柄
	 * @auther      lyl
	 * @param [in]  mysql     : Mysql连接句柄
	 * @return      bool      : false表示连接失败,true表示连接成功
	 */
	bool Reconnect(MYSQL* mysql);

	/*
	 * @brief       获取Mysql句柄
	 * @auther      lyl
	 * @return      MYSQL*    : NULL表示未连接,其他表示Mysql句柄
	 * @note        连接池中没有连接句柄,会阻塞等
	 */
	inline MYSQL* GetMysql() {
		return m_mysql;
	}

	/*
	 * @brief       返回Mysql句柄
	 * @auther      lyl
	 * @param [in]  mysql      : Mysql句柄
	 * @return      void
	 * @note        将GetMysql获取的连接句柄返回至连接池
	 */
	inline void SetMysql(MYSQL* mysql) {

	}

	/*
	 * @brief       获取Mysql最后操作的错误信息
	 * @auther      lyl
	 * @param [in]  mysql      : Mysql句柄
	 * @return      const char* : NULL表示无错误,其他表示错误信息
	 */
	inline const char *GetErrMsg(MYSQL* mysql = NULL) const {
		if (NULL == mysql)
			mysql = m_mysql;
		return mysql_error(mysql);
	}
protected:
	/*
	 * @brief       断开Mysql
	 * @auther      lyl
	 * @return      void
	 * @note        暂不支持对外断开连接,如需对外需要对m_init操作加锁
	 */
	void Disconnect();
private:
	bool m_init;
	MYSQL* m_mysql;
	std::string m_host;
	int m_port;
	std::string m_username;
	std::string m_password;
	std::string m_db;
};

/*
 * @brief       Mysql操作及结果集
 * @auther      lyl
 */
class CDBQuery {
public:
	CDBQuery();
	virtual ~CDBQuery();

	/*
	 * @brief       		执行Sql语句
	 * @auther      		lyl
	 * @param 		[in]  	mysql  			: Mysql句柄
	 * @param 		[in]  	sql    			: sql语句
	 * @return      bool   : false表示执行失败,true表示执行成功
	 */
	bool ToQuery(CDBMysql* mysql, const char *sql);

	/*
	 * @brief       获取结果集
	 * @auther      lyl
	 * @return      MYSQL_ROW : NULL表示无结果,其他表示一条结果
	 */
	inline MYSQL_ROW GetFetchRow() {
		if (NULL == m_result) {
			return NULL;
		}
		return mysql_fetch_row(m_result);
	}

	/*
	 * @brief       获取结果集的列数
	 * @auther      zlw
	 * @return      int32_t : -1表示出错,其他表示结果
	 */
	inline int32_t GetFieldCount() {
		if (NULL == m_result)
			return -1;
		return m_result->field_count;
	}

	/*
	 * @brief       获取自增ID
	 * @auther      lyl
	 * @return      int32_t : 表示自增ID
	 */
	inline uint64_t GetInsertId() const { return mysql_insert_id(m_myMysql); }
private:
	MYSQL_RES* m_result;
	MYSQL* m_myMysql;
	CDBMysql* m_DBMysql;
};

#ifdef	__cplusplus
}
#endif

#endif /* PMYSQLAPI_H_ */
